#include "Bot.h"
#include "Order.h"
#include "Strategy.hh"

using namespace std;


//constructor
Bot::Bot()
{

}

//plays a single game of Ants.
void Bot::playGame()
{
    TRACK();

    //reads the game parameters and sets up
    cin >> state;
    state.setup();
    //set random positions to explore
    endTurn();

    Map::GlobalMap = state.map;

    //continues making moves while the game is not over
    while(cin >> state)
    {
        state.updateVisionInformation();
        makeMoves();
        endTurn();
    }
}

//makes the bots moves for the turn
void Bot::makeMoves()
{
    TRACK();

    bug << "turn " << state.turn << ":" << endl;
    bug << state << fflush << endl;

    Order order;
	
    // update food count 
    update_hive_estimate_before_turn(state);


    //update our knowledge of the map and recover all known places
    update_map_knowledge(state, map_knowledge);

    //set attractiveness of places based on known food and hills
    set_potentials(state);

    //assign 1 or 2 ants to known food places
    bug << "food" << std::endl;
    assign_to_food(state, order);

    //assign up to 10 ants to known enemy hills
    bug << "hills" << std::endl;
    assign_to_raze_hills(state, order);

    bug << "myhills security" << std::endl;
    assign_to_guard(state, order);
    
    //picks out moves for each ant
    for(int ant=0; ant<(int)state.myAnts.size(); ant++)
    {

#if 0
      // no move option
      order.proposeMove(state, state.myAnts[ant], state.myAnts[ant], -1, state.location(state.myAnts[ant]).value);
#endif
      // find out direction of last move for this ant
      int cur_d=-1;
      std::map<uLocation,int>::const_iterator it_aim = state.last_aim.find(state.myAnts[ant]);
      if(it_aim != state.last_aim.end())
          cur_d=it_aim->second;

      for(int d=0; d<Torus::TDIRECTIONS; d++)
        {
            uLocation newloc = state.getLocation(state.myAnts[ant], d);
            if(!state.grid().at(newloc).isWater)
            {
                double value = state.location(newloc).value;
                if(cur_d==d) value *= 1.1; // prefer not changing direction
                order.proposeMove(state, state.myAnts[ant], newloc, d, value);
            }
	}
    }

    bug << "order size: " << order.size() << endl << endl;

#if 0
    Simulator sim(state);
    Order clone_orders(order);
    sim.simulate_one_step(clone_orders);
    if(sim.death!=0)
    {
        bug << "battle issue: " << sim.death << endl << endl;
    }
#endif

    order.execute(state);
	
    // try to estimate food reserve (hive)
    update_hive_estimate_after_turn(state);

    bug << "time taken: " << state.timer.getTime() << "ms" << endl << endl;
}

//finishes the turn
void Bot::endTurn()
{
    TRACK();

    if(state.turn > 0)
        state.reset();
    state.turn++;

    cout << "go" << endl;
}
